﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace WenSkin.Controls
{
    [ToolboxBitmap(typeof(TabControl))]
    public partial class WenTabControl : System.Windows.Forms.TabControl
    {
        public WenTabControl() : base()
        {
            this.DrawMode = TabDrawMode.OwnerDrawFixed;
            this.SizeMode = TabSizeMode.Fixed;
            this.ItemSize = new Size(120, 25);

            base.SetStyle(
                ControlStyles.UserPaint |
                ControlStyles.DoubleBuffer |
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();
        }

        #region 私有属性

        private int mouseMovePageIndex = -1;
        private bool mouseMovePageColse = false;
        private bool closeButtonEnable = true;
        private bool iconEnable=false;

        #endregion

        #region 公有属性

        [Category("Wen")]
        [Description("背景图片")]
        public Image BackImage { get; set; }

        [Category("Wen"), Description("是否显示关闭按钮")]
        public bool CloseButtonEnable { get => closeButtonEnable; set { closeButtonEnable = value; this.Invalidate(); } }

        [Category("Wen"), Description("是否显示图标"), DefaultValue(false)]
        public bool IconEnable { get => iconEnable; set => iconEnable = value; }
        #endregion

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SetGDIHigh();
            //base.OnPaint(e);
            Rectangle rec = this.ClientRectangle;

            Control control = this.Parent;
            Color color = control.BackColor;
            Brush brush = new SolidBrush(color);

            if (BackImage != null)
            {
                g.DrawImage(BackImage, new Rectangle(-2, -2, this.Width + 4, this.Height + 4));
            }
            else
            {
                g.FillRectangle(brush, new Rectangle(-2, -2, this.Width + 4, this.Height + 4));
            }
            StringFormat stringFormat = new StringFormat(StringFormatFlags.NoWrap)
            {
                Alignment = StringAlignment.Near,
                LineAlignment = StringAlignment.Center
            };

            //画一条长底纹实线条
            Rectangle recLine = new Rectangle(0, this.ItemSize.Height + 2, this.Width, 1);
            using (Brush b = new SolidBrush(Color.FromArgb(0, 122, 204)))
            {
                g.FillRectangle(b, recLine);
            }


            //获取当前选中项目索引
            int selectIndex = this.SelectedIndex;
            foreach (TabPage tab in this.TabPages)
            {
                int index = this.TabPages.IndexOf(tab);
                Rectangle rectab = this.GetTabRect(index);

                //背景颜色
                Brush back = new SolidBrush(color);

                if (index == selectIndex)
                    back = new SolidBrush(Color.FromArgb(0, 122, 204));

                //绘制选中底纹
                g.FillRectangle(back, rectab);

                ////绘制文字区域
                //Rectangle recStr = new Rectangle(rectab.X, rectab.Y, rectab.Width - 20, rectab.Height);
                ////绘制文字
                //g.DrawString(tab.Text, tab.Font, new SolidBrush(tab.ForeColor), recStr, stringFormat);

                ImageIcoOrText(tab, g, rectab);

                //绘制关闭按钮
                if (index == selectIndex)
                    CloseButton(g, rectab, false);

                //注销内存
                back.Dispose();
            }
            stringFormat.Dispose();
        }

        //画tab图标和文字
        private void ImageIcoOrText(TabPage tabPage, Graphics g, Rectangle rec)
        {
            StringFormat stringFormat = new StringFormat(StringFormatFlags.NoWrap)
            {
                Alignment = StringAlignment.Near,
                LineAlignment = StringAlignment.Center
            };
            if (IconEnable && tabPage is WenTabPage page && page.Image != null)
            {
                //绘制图标区域
                Rectangle recimage = new Rectangle(rec.X + 3, rec.Y + (rec.Height - 16) / 2, 16, 16);
                g.DrawImage(page.Image, recimage);

                //绘制文字区域
                Rectangle recStr = new Rectangle(recimage.X + recimage.Width + 3, rec.Y, rec.Width - 20 - (recimage.Width + 6), rec.Height);
                g.DrawString(page.Text, page.Font, new SolidBrush(page.ForeColor), recStr, stringFormat);
            }
            else
            {
                //绘制文字区域
                Rectangle recStr = new Rectangle(rec.X, rec.Y, rec.Width - 20, rec.Height);
                //绘制文字
                g.DrawString(tabPage.Text, tabPage.Font, new SolidBrush(tabPage.ForeColor), recStr, stringFormat);
            }
        }

        //关闭按钮功能
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            //关闭按钮不显示，功能取消
            if (!closeButtonEnable)
                return;

            if (e.Button == MouseButtons.Left)
            {
                if (mouseMovePageColse && mouseMovePageIndex > -1)
                {
                    this.TabPages.RemoveAt(mouseMovePageIndex);
                }
            }
        }

        //绘制关闭按钮
        private void CloseButton(Graphics g, Rectangle rec, bool close)
        {
            //当不显示关闭按钮直接返回
            if (!closeButtonEnable)
                return;

            int closeSize = 8;

            //获取关闭按钮Y需要移动区域 便于按钮居中
            int yMove = (ItemSize.Height - closeSize) / 2;

            //偏移矩形框
            rec.Offset(rec.Width - closeSize - 5, yMove);
            //重新设置矩形框的大小
            rec.Width = closeSize;
            rec.Height = closeSize;

            //如果关闭为True绘制圆圈背景效果
            if (close)
                g.FillEllipse(Brushes.DarkGray, rec.X - 4, rec.Y - 4, 16, 16);

            //用DrawLine绘制两条线段  实现X  样子效果
            using Pen pen = new Pen(Color.Gray)
            {
                Width = 2
            };
            g.DrawLine(pen, rec.X, rec.Y, rec.X + closeSize, rec.Y + closeSize);
            g.DrawLine(pen, rec.X, rec.Y + closeSize, rec.X + closeSize, rec.Y);
        }
        //鼠标移动事件
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            int beforeMouseIndex = mouseMovePageIndex;
            foreach (TabPage tab in this.TabPages)
            {
                int index = this.TabPages.IndexOf(tab);
                if (this.GetTabRect(index).Contains(e.Location))
                {
                    mouseMovePageIndex = index;
                }
            }

            if (mouseMovePageIndex == -1 || mouseMovePageIndex >= this.TabPages.Count)
                return;
            //获取关闭区域
            int closeSize = 20;
            Rectangle rec = this.GetTabRect(mouseMovePageIndex);

            //检查关闭区域
            Rectangle recClose = this.GetTabRect(mouseMovePageIndex);
            recClose.Offset(recClose.Width - closeSize, 4);
            recClose.Width = closeSize;
            recClose.Height = closeSize;

            bool mouseMovePageColse = this.mouseMovePageColse;

            if (recClose.Contains(e.Location))
            {
                this.mouseMovePageColse = true;
            }
            else
            {
                this.mouseMovePageColse = false;
            }

            //判定鼠标是否已经改变项
            if (beforeMouseIndex == mouseMovePageIndex && mouseMovePageColse == this.mouseMovePageColse)
            {
                return;
            }

            Graphics g = this.CreateGraphics();
            g.SetClip(new Rectangle(rec.X + 1, rec.Y + 1, rec.Width - 2, rec.Height - 2));
            //鼠标移动改变两处重绘
            if (this.mouseMovePageColse)
            {
                DrawTabPageLable(g, this.TabPages[mouseMovePageIndex], rec, Color.FromArgb(28, 151, 234), true);
            }
            else
            {
                DrawTabPageLable(g, this.TabPages[mouseMovePageIndex], rec, Color.FromArgb(28, 151, 234), false);
            }

            int selectIndex = this.SelectedIndex;
            Control control = this.Parent;
            Color color = control.BackColor;

            if (beforeMouseIndex == selectIndex)
                color = Color.DodgerBlue;

            //改变后的上一个信息
            if (beforeMouseIndex != -1 && beforeMouseIndex != mouseMovePageIndex && beforeMouseIndex < this.TabPages.Count)
            {
                Rectangle recBefore = this.GetTabRect(beforeMouseIndex);
                g.SetClip(recBefore);
                DrawTabPageLable(g, this.TabPages[beforeMouseIndex], recBefore, color, null);
            }
        }

        //画标签
        private void DrawTabPageLable(Graphics g, TabPage tab, Rectangle rec, Color color, bool? colse)
        {
            g.SetGDIHigh();
            using StringFormat stringFormat = new StringFormat(StringFormatFlags.NoWrap)
            {
                Alignment = StringAlignment.Near,
                LineAlignment = StringAlignment.Center
            };

            //声明画笔
            using Brush brushe = new SolidBrush(color);
            using Brush brusheStr = new SolidBrush(tab.ForeColor);
            //绘制选中底纹
            g.FillRectangle(brushe, rec);

            ////绘制文字区域
            //Rectangle recStr = new Rectangle(rec.X, rec.Y, rec.Width - 20, rec.Height);
            ////绘制文字
            //g.DrawString(tab.Text, tab.Font, brusheStr, recStr, stringFormat);

            ImageIcoOrText(tab, g, rec);

            //绘制关闭按钮
            if (colse == null)
            {
                if (this.SelectedTab == tab)
                {
                    CloseButton(g, rec, false);
                }
                return;
            }

            if (colse == true)
                CloseButton(g, rec, true);
            else
                CloseButton(g, rec, false);

        }

        //鼠标离开事件
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            if (mouseMovePageIndex == -1 || mouseMovePageIndex >= this.TabPages.Count)
                return;

            Graphics g = this.CreateGraphics();

            int selectIndex = this.SelectedIndex;
            Control control = this.Parent;
            Color color = control.BackColor;

            if (mouseMovePageIndex == selectIndex)
                color = Color.DodgerBlue;
            //设置rec大小
            Rectangle recBefore = this.GetTabRect(mouseMovePageIndex);
            g.SetClip(recBefore);

            DrawTabPageLable(g, this.TabPages[mouseMovePageIndex], recBefore, color, null);
            mouseMovePageIndex = -1;
        }

        protected override void OnControlRemoved(ControlEventArgs e)
        {
            base.OnControlRemoved(e);
            mouseMovePageIndex = -1;
        }
    }
}